<template>
  <!-- <div class="containers"> -->
  <div class="canvas" ref="canvas"></div>
  <!-- </div> -->
</template>

<script>
// 引入相关的依赖
import $ from "jquery";
import { query as domQuery } from "min-dom";
import BpmnModeler from "bpmn-js/lib/Modeler";
import CustomModule from "@/components/bpmn-custom/custom/index";
import { append as svgAppend, attr as svgAttr, create as svgCreate } from "tiny-svg";
import { mapActions } from "vuex";
const HIGH_PRIORITY = 1500;
export default {
  name: "",
  props: {
    canShow: {
      type: Boolean,
      default: true,
    },
    procDefId: {
      type: String,
      default: "",
    },
    procInstId: {
      type: String,
      default: "",
    },
    showImgVisible: {
      type: Boolean,
      default: false,
    },
  },
  components: {},
  // 生命周期 - 创建完成（可以访问当前this实例）
  created() {},
  // 生命周期 - 载入后, Vue 实例挂载到实际的 DOM 操作完成，一般在该过程进行 Ajax 交互
  async mounted() {
    await this.generateBpmImageDataByProcInstId();
    // this.changeColor();
  },
  data() {
    return {
      // bpmn建模器
      bpmnModeler: null,
      container: null,
      canvas: null,
      highLightedActivitiesIds: [],
      runningActivitiesIds: [],
      show: false,
    };
  },
  // 方法集合
  methods: {
    ...mapActions(["setHighLightedActivitiesIds"]),
    ...mapActions(["setRunningActivitiesIds"]),
    // axios请求获取已完成的id数组和正在进行的id数组
    async generateBpmImageDataByProcInstId() {
      const { resourceXml, highLightedActivitiesIds, runningActivitiesIds } =
        await this.$Sys.request.get(
          "generateBpmImageDataByProcInstId",
          {},
          {
            // procDefId: 'basicResourcesChange:6:1507195068317044736',
            // proInsId: '1504355943494848512',
            procDefId: this.procDefId,
            proInsId: this.procInstId,
          }
        );
      // 存储到vuex里，之后在CustomRenderer.js里获取
      this.setHighLightedActivitiesIds(highLightedActivitiesIds);
      this.setRunningActivitiesIds(runningActivitiesIds);
      // 获取到属性ref为“canvas”的dom节点
      const canvas = this.$refs.canvas;
      // 建模
      this.bpmnModeler = new BpmnModeler({
        container: canvas,
        additionalModules: [
          CustomModule,
          {
            labelEditingProvider: ["value", ""], //禁用节点编辑
            contextPadProvider: ["value", ""], //禁用图形菜单
            bendpoints: ["value", {}], //禁用连线拖动
            // zoomScroll: ["value", ""], //禁用滚动
            // moveCanvas: ['value', ''], //禁用拖动整个流程图
            move: ["value", ""], //禁用单个图形拖动
          },
        ],
      });
      this.bpmnModeler
        .importXML(resourceXml)
        .then(() => {
          const marker = svgCreate("marker");
          const markerActivities = svgCreate("marker");

          svgAttr(marker, {
            id: "sequenceflow-arrow-normal",
            viewBox: "0 0 20 20",
            refX: "11",
            refY: "10",
            markerWidth: "10",
            markerHeight: "10",
            orient: "auto",
          });

          svgAttr(markerActivities, {
            id: "sequenceflow-arrow-activities",
            viewBox: "0 0 20 20",
            refX: "11",
            refY: "10",
            markerWidth: "10",
            markerHeight: "10",
            orient: "auto",
          });

          const path = svgCreate("path");
          const pathActivities = svgCreate("path");

          svgAttr(path, {
            d: "M 1 5 L 11 10 L 1 15 Z",
            style:
              " stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: #cccccc;fill:#ccc;",
          });
          svgAttr(pathActivities, {
            d: "M 1 5 L 11 10 L 1 15 Z",
            style:
              " stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: #fdb039;fill:#fdb039;",
          });

          const defs = domQuery("defs");
          svgAppend(marker, path);
          svgAppend(defs, marker);
          svgAppend(markerActivities, pathActivities);
          svgAppend(defs, markerActivities);

          // 让图能自适应屏幕
          const canvas = this.bpmnModeler.get("canvas");
          canvas.zoom("fit-viewport", "auto"); //画布自适应居中
          this.canShow ? canvas.zoom(0.4) : canvas.zoom(0.8); //缩放倍数
          // 这里是成功之后的回调, 可以在这里做一系列事情
          this.success();
        })
        .catch((err) => {
          if (err) {
            console.error(err);
          }
        });
    },
    // 改变节点颜色的其中一种方法，用juery改变，最终我选择了在CustomRenderer.js里用继承bpnm的drawConnection的方法改变
    changeColor() {
      this.highLightedActivitiesIds.map((item) => {
        $(`g[data-element-id=${item}] g`)
          .removeClass("unActivities")
          .removeClass("running")
          .addClass("Activities");
      });
      this.runningActivitiesIds.map((item) => {
        $(`g[data-element-id=${item}] g`)
          .removeClass("unActivities")
          .removeClass("Activities")
          .addClass("running");
      });
    },
    success() {
      console.log("创建成功!");
      this.addBpmnListener();
    },
    addBpmnListener() {
      const that = this;
      // 获取a标签dom节点
      const downloadLink = this.$refs.saveDiagram;
      // 点击图时被另一个弹窗组件引用作为弹窗弹出
      this.bpmnModeler.on("element.click", function () {
        let showImgVisible = !that.showImgVisible;
        // 通过canShow的改变，分成bpmn图是否在弹窗里两种情况做事件处理，在弹窗里时点击节点不应把showImgVisible同步给弹窗组件
        if (that.canShow) {
          that.$emit("update:showImgVisible", showImgVisible);
        }
      });
      // 给图绑定事件，当图有发生改变就会触发这个事件
      // this.bpmnModeler.on('commandStack.changed', function() {
      //   that.saveDiagram(function(err, xml) {
      //     that.setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml);
      //   });
      // });
    },
    // 额外的方法，在本项目中没用到
    // 下载为bpmn格式,done是个函数，调用的时候传入的
    saveDiagram(done) {
      // 把传入的done再传给bpmn原型的saveXML函数调用
      this.bpmnModeler.saveXML({ format: true }, function (err, xml) {
        done(err, xml);
      });
    },
    // 当图发生改变的时候会调用这个函数，这个data就是图的xml
    setEncoded(link, name, data) {
      // 把xml转换为URI，下载要用到的
      const encodedData = encodeURIComponent(data);
      // 下载图的具体操作,改变a的属性，className令a标签可点击，href令能下载，download是下载的文件的名字
      let xmlFile = new File([data], "test.bpmn");
      //   console.log(xmlFile)
      if (data) {
        link.className = "active";
        link.href = "data:application/bpmn20-xml;charset=UTF-8," + encodedData;
        link.download = name;
      }
    },
  },
  // 计算属性
  computed: {},
};
</script>

<style lang="less" scoped>
@import "~@/components/bpmn-custom/customRenderer.less";
</style>
